package Volume1.ch5;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Scanner;

/**
 * 使用反射输出类的所有特性
 *
 * @Auther jacob
 * @Date 2020/8/6
 */
public class ReflectionTest {

    public static void main(String[] args) {
        // 从输入参数或者控制台获取类名
        String name;
        if (args.length > 0) {
            name = args[0];
        } else {
            Scanner in = new Scanner(System.in);
            System.out.println("请输入类名（如：java.util.Date）：");
            name = in.next();
        }

        try {
            // 输出类名及其父类的名称（当父类不为object类时输出父类名称）
            Class cl = Class.forName(name);
            Class superCl = cl.getSuperclass();
            // 获取该类的修饰符，public、private、protected、static
            String modifiers = Modifier.toString(cl.getModifiers());
            if (modifiers.length() > 0) {
                System.out.println("modifiers = " + modifiers);
            }
            // 获取父类
            if (superCl != null && superCl != Object.class) {
                System.out.println("extends = " + superCl.getName());
            }
            System.out.println("{");

            // 输出所有的构造函数
            printConstructor(cl);
            System.out.println();
            // 输出所有的方法
            printMethods(cl);
            System.out.println();
            // 输出所有的成员变量
            printFields(cl);
            System.out.println("}");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 输出类的所有构造函数
     *
     * @param cl a class
     */
    public static void printConstructor(Class cl) {
        Constructor[] constructors = cl.getConstructors();

        for (Constructor c : constructors) {
            String name = c.getName();
            System.out.print("  ");
            String modifiers = Modifier.toString(c.getModifiers());
            if (modifiers.length() > 0) {
                System.out.print(modifiers + "  ");
            }
            System.out.print(name + "(");

            // 获取参数类型
            Class[] paramTypes = c.getParameterTypes();
            for (int i = 0; i < paramTypes.length; i++) {
                if (i > 0) {
                    System.out.print(", ");
                }
                System.out.print(paramTypes[i].getName());
            }
            System.out.println(");");
        }
    }

    /**
     * 输出类的所有方法
     *
     * @param cl a class
     */
    public static void printMethods(Class cl) {
        Method[] methods = cl.getMethods();

        for (Method method : methods) {
            Class<?> retType = method.getReturnType();
            String name = method.getName();
            System.out.print("  ");

            // 输出属性、返回类型和方法名
            String modifiers = Modifier.toString(method.getModifiers());
            if (modifiers.length() > 0) {
                System.out.print(modifiers + " ");
            }
            System.out.print(retType.getName() + " " + name + "(");

            // 输出参数类型
            Class<?>[] parameterTypes = method.getParameterTypes();
            for (int i = 0; i < parameterTypes.length; i++) {
                if (i > 0) {
                    System.out.print(", ");
                }
                System.out.print(parameterTypes[i].getName());
            }
            System.out.println(");");
        }
    }

    /**
     * 输出类的成员变量
     * @param cl a class
     */
    public static void printFields(Class cl){
        Field[] fields = cl.getDeclaredFields();
        for (Field field : fields) {
            Class<?> type = field.getType();
            String name = field.getName();
            System.out.print("  ");
            String modifier = Modifier.toString(field.getModifiers());
            if (modifier.length() > 0){
                System.out.print(modifier + " ");
            }
            System.out.println(type.getName() + " " + name + ";");

        }

    }

}
